home *** CD-ROM | disk | FTP | other *** search
- #include "pcx.h"
- #include "output.h"
-
- void put_pcx_header(FILE* f, pcxheader* p, loc sz, int pal, int planes)
- {
- if(pal)
- get_pcx_header("color.sys", p);
-
- p->bitpx = 1;
- p->nplanes = planes;
-
- p->x1 = 0; p->y1 = 0; p->x2 = sz.X - 1; p->y2 = sz.Y - 1;
-
- p->hres = getmaxx() + 1; /* horiz. resolution of display */
- p->vres = getmaxy() + 1; /* vert. resolution of display */
- p->bplin = (sz.X + 7) >> 3; /* Bytes per line */
-
- p->palinfo = 1; /* Palette info (1=col.,2 = grey) */
-
- if(f != NULL)
- fwrite(p, 128, 1, f);
- }
- /////////////////////////
- int get_pcx_header(pcxstream* s, pcxheader* p_h)
- {
- s->read((uchar*)p_h, sizeof(pcxheader));
- return 1;
- }
- ////////////////////////
- int get_pcx_header(FILE* file, pcxheader* p_h)
- {
- return fread(p_h, sizeof(pcxheader), 1, file);
- }
- ////////////////////////
- int get_pcx_header(char* fname, pcxheader* p_h)
- {
- FILE* f;
- if((f = fopen(fname, "rb")) == NULL)
- return 0;
- pcxheader p;
- get_pcx_header(f, p_h);
- fclose(f);
- return 1;
- }
- ///////////////////////////
- inline void pcx_put_char(uchar count, uchar ch, FILE* f)
- {
- if(count > 1 || (0xC0 == (0xC0 & ch)))
- fputc(count | 128 | 64, f); // Write counter
- fputc(ch, f); // Write pattern
- }
- //////////////////////////
- void pcx_scr_file(rect coord, char* name, int pal)
- {
- pal = 1;
- FILE* f = fopen(name, "wb");
-
- if(coord.corner.X > getmaxx())
- coord.corner.X = getmaxx();
-
- pcxheader p;
- put_pcx_header(f, &p, loc(coord.width(), coord.height()), pal);
-
- imageP image = (imageP)malloc(imagesize(0, 0, coord.width(), 0));
-
- int x; int y = 0; int count = 1;
- int plane;
- plane = x = (N_PLANES - 1) * p.bplin; // start of last plane
- int shift = 2 * p.bplin;
- int height = p.y2 - p.y1 + 1;
-
- getimage(coord.origin.X, coord.origin.Y,
- coord.corner.X, coord.origin.Y, image);
-
- unsigned char ch = image->data[x];
-
- while(1)
- {
- x++;
- if(!(x % p.bplin)) // end of scan line or end of plane
- {
- if(x != p.bplin) // not the end of scan line
- x -= shift;
- else // end of scan line
- {
- if(y < height) // not last scan line
- {
- x = plane;
- y++;
- getimage(coord.origin.X, coord.origin.Y + y,
- coord.corner.X, coord.origin.Y + y, image);
- /* The following code, marked !! is absolutely unnecessary and ineffective.
- But Painbrush use stop-on-the-scan-line technology. I don't know why.
- This code is compatible with Paintbrush.
- */
- pcx_put_char(count, ch, f); // !!
- count = 0; // !!
- ch = image->data[x]; // !!
-
- }
- else // last scan line
- {
- pcx_put_char(count, ch, f);
- break;
- }
- }
- }
-
- if(ch == image->data[x])
- {
- if(count == 63)
- {
- pcx_put_char(count, ch, f);
- count = 1;
- }
- else
- count++;
- }
- else
- {
- pcx_put_char(count, ch, f);
- count = 1;
- ch = image->data[x];
- }
- }
- delete image;
- fclose(f);
- }
- ////////////////////////
- int pcx_file_scr(char* name, loc pos, int* cells, int mode)
- {
- if(cells[0] == -1)
- return 1;
- FILE* f = fopen(name, "rb");
- pcxheader p;
-
- if(f == NULL)
- {
- fclose(f);
- return 0;
- }
- pcxstream pcxF(f);
- get_pcx_header(&pcxF, &p);
-
- if(1 != p.bitpx || N_PLANES != p.nplanes) // incompatible modes
- return 0;
-
- imageP image = (imageP)malloc(p.bplin * N_PLANES + sizeof(imageType));
-
- image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
- image->ymax = 0;
-
- int x; int y = 0; int count;
- int plane;
-
- plane = x = (p.nplanes - 1) * p.bplin; // start of last plane
- int shift = 2 * p.bplin;
- int height = p.y2 - p.y1 + 1;
- int height1;
- if(cells != NULL)
- {
- int i = 0;
- while(cells[i] != -1)
- i++;
- height1 = (cells[i - 1] + 80) / 80 * pScreenSet->cell_height
- - pos.Y;
- height = height > height1 ? height1 : height;
- }
- int top = cells == NULL ? 0
- : cells[0] / 80 * pScreenSet->cell_height - pos.Y;
- imageP work = (imageP)malloc(p.bplin * N_PLANES + sizeof(imageP));
- work->ymax = 0;
-
- while(y <= height)
- {
- unsigned char ch = pcxF.get(); // read char
- if((ch & 0xC0 )==0xC0) // if two upper bits == 1
- {
- count = 63 & ch; // use 6 low bits as counter
- ch = pcxF.get();
- for(int j = 0; j < count; j++)
- {
- image->data[x] = ch;
- x++;
- if(x == p.bplin)
- {
- if(y >= top)
- putimage(pos.X, pos.Y + y, image, cells, work,
- p.bplin, mode);
- x = plane;
- y++;
- }
- else
- if(!(x % p.bplin))
- x -= shift;
- }
- }
- else
- {
- (unsigned char)(image->data[x]) = ch;
- x++;
- if(x == p.bplin)
- {
- if(y >= top)
- putimage(pos.X, pos.Y + y, image, cells, work, p.bplin,
- mode);
- x = plane;
- y++;
- }
- else
- if(!(x % p.bplin))
- x -= shift;
- }
- }
- delete image;
- delete work;
- fclose(f);
- return 1;
- }
- //////////////////////////
- /*
- void main()
- {
- if(!init_KNOW_HOW())
- return;
-
- // int LIST[] = { 40, 120, 200, 280, 360, 440, 520, -1 };
-
- // pcx_file_scr("about.pcz", loc(0, 0), LIST, COPY_PUT);
- pcx_file_scr("g.pcx", loc(0, 0));
- pcx_scr_file(rect(64, 40, 191, 300), "work.pcx", 1);
- pcx_file_scr("work.pcx", loc(0, 0));
- close_KNOW_HOW();
- closegraph();
- }
-
- */